package com.analysis.utils;

import com.analysis.dto.Reference;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Date 2025/9/5
 * @Author 蒋棒
 */
public class ParseTextUtils {

    // 预编译正则表达式，避免重复编译
    private static final Pattern PATTERN_TOOL_NAME = Pattern.compile("\\*\\*([^*]+)\\*\\*：");
    private static final Pattern PATTERN_BANKING_TOOLS = Pattern.compile("\\d+\\.\\s*\\*\\*([^*]+)\\*\\*");
    // 新增：支持以粗体包裹的编号列表，例如：**1. MarketUP**
    private static final Pattern PATTERN_BOLD_NUMBERED = Pattern.compile("\\*\\*\\s*\\d+\\.\\s*([^*]+?)\\s*\\*\\*");
    private static final Pattern PATTERN_NUMBERED_LINE = Pattern.compile("^\\d+\\.");

    // 新增：处理 ### 数字. 工具名称 —— 描述 格式的正则表达式
    private static final Pattern PATTERN_MARKDOWN_TOOLS = Pattern.compile("###\\s*\\d+\\.\\s*([^——]+?)\\s*——");

    // 预编译标题与URL的行级正则（忽略大小写，兼容"示例"，可选（说明），中/英文冒号）
    private static final Pattern TITLE_LINE = Pattern.compile("(?i)^[-\\s]*\\*\\*(title(?:示例)?)\\*\\*\\s*(?:（[^）]*）)?[：:]\\s*(.+)\\s*$");
    private static final Pattern URL_LINE = Pattern.compile("(?i)^[-\\s]*\\*\\*(url(?:示例)?)\\*\\*\\s*(?:（[^）]*）)?[：:]\\s*(.+)\\s*$");

    // 新增：支持 **Title:** 和 **URL:** 格式的正则表达式
    // 支持格式：*   **Title:** 或 **title:** 或 **title示例:** 等
    private static final Pattern TITLE_LINE_NEW = Pattern.compile(".*\\*\\*title(?:示例)?:\\*\\*\\s+(.+)");
    private static final Pattern URL_LINE_NEW = Pattern.compile(".*\\*\\*url(?:示例)?:\\*\\*\\s+(.+)");

    // 新增：支持 *   **标题**: 和 *   **URL**: 格式的正则表达式（testReferences2格式）
    private static final Pattern TITLE_LINE_BULLET = Pattern.compile(".*\\*\\*标题\\*\\*\\s*:\\s*(.+)");
    private static final Pattern URL_LINE_BULLET = Pattern.compile(".*\\*\\*URL\\*\\*\\s*:\\s*(.+)");

    // 常量定义
    private static final int MAX_RESULTS = 10;
    private static final int VALID_MAX_RESULTS = 10;

    // 缓存配置
    private static final int MAX_CACHE_SIZE = 1000;
    private static final long CACHE_EXPIRE_TIME = 30 * 60 * 1000; // 30分钟

    // 字符串常量 - 避免重复创建
    private static final String EMPTY_STRING = "";
    private static final String SPACE = " ";
    private static final String NEWLINE = "\n";
    private static final String ASTERISK = "*";
    private static final String COLON = ":";
    private static final String CHINESE_COLON = "：";
    private static final String SEMICOLON = ";";
    private static final String CHINESE_SEMICOLON = "；";
    private static final String DOT = ".";
    private static final String CHINESE_DOT = "、";
    private static final String DASH = "-";
    private static final String BULLET = "•";
    private static final String MIDDLE_DOT = "·";

    // 字符常量 - 避免重复装箱
    private static final char CHAR_SPACE = ' ';
    private static final char CHAR_TAB = '\t';
    private static final char CHAR_NEWLINE = '\n';
    private static final char CHAR_ASTERISK = '*';
    private static final char CHAR_COLON = ':';
    private static final char CHAR_CHINESE_COLON = '：';
    private static final char CHAR_SEMICOLON = ';';
    private static final char CHAR_CHINESE_SEMICOLON = '；';
    private static final char CHAR_DOT = '.';
    private static final char CHAR_CHINESE_DOT = '、';
    private static final char CHAR_DASH = '-';
    private static final char CHAR_BULLET = '•';
    private static final char CHAR_MIDDLE_DOT = '·';

    /**
     * 通用解析text - 性能优化版本
     * <p>
     * 优化策略：
     * 1. 预编译正则表达式，避免重复编译
     * 2. 按优先级顺序尝试解析，找到合适结果后立即返回
     * 3. 使用更高效的字符串操作
     * 4. 添加结果数量验证，避免无效解析
     *
     * @param text 待解析的文本
     * @return 解析结果列表
     */
    public static List<String> parseCommonText(String text) {
        if (text == null || text.isEmpty()) {
            return new ArrayList<>();
        }
        // ### **1. 数商云（广州市数商云网络科技有限公司）**
        List<String> contents = parseBoldMarkdownText(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  ### 1. 工具名称 ——
        contents = parseMarkdownToolsOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  **1. 工具名称**（粗体编号标题）
        contents = parseBoldNumberedList(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //   ### 1. 工具名称
        contents = parseMarkdownText(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  数字. **工具名称**
        contents = parseBankingToolsOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  **工具名称**：
        contents = parseTextOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        // 数字开头的列表格式
        contents = parseBrandsFromTextOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        // 兜底方案 - 使用原始方法
        return parseText(text);
    }

    /**
     * 通用解析text - 性能优化版本
     * <p>
     * 优化策略：
     * 1. 预编译正则表达式，避免重复编译
     * 2. 按优先级顺序尝试解析，找到合适结果后立即返回
     * 3. 使用更高效的字符串操作
     * 4. 添加结果数量验证，避免无效解析
     *
     * @param text 待解析的文本
     * @return 解析结果列表
     */
    public static List<String> brandAnalysis(String text) {
        if (text == null || text.isEmpty()) {
            return new ArrayList<>();
        }
        // ### **1. 数商云（广州市数商云网络科技有限公司）**
        List<String> contents = parseBoldMarkdownText(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  ### 1. 工具名称 ——
        contents = parseMarkdownToolsOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  **1. 工具名称**（粗体编号标题）
        contents = parseBoldNumberedList(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //   ### 1. 工具名称
        contents = parseMarkdownText(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  数字. **工具名称**
        contents = parseBankingToolsOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  **工具名称**：
        contents = parseTextOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        // 数字开头的列表格式
        contents = parseBrandsFromTextOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        // 兜底方案 - 使用原始方法
        contents = parseText(text);
        if (isValidResult(contents)) {
            return contents;
        }
        return splitTextByLine(text);
    }

    /**
     * 通用解析text - 性能优化版本
     * <p>
     * 优化策略：
     * 1. 预编译正则表达式，避免重复编译
     * 2. 按优先级顺序尝试解析，找到合适结果后立即返回
     * 3. 使用更高效的字符串操作
     * 4. 添加结果数量验证，避免无效解析
     *
     * @param text 待解析的文本
     * @return 解析结果列表
     */
    public static List<String> parseDeepseekText(String text) {
        if (text == null || text.isEmpty()) {
            return new ArrayList<>();
        }
        // ### **1. 数商云（广州市数商云网络科技有限公司）**
        List<String> contents = parseBoldMarkdownText(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  ### 1. 工具名称 ——
        contents = parseMarkdownToolsOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  **1. 工具名称**（粗体编号标题）
        contents = parseBoldNumberedList(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //   ### 1. 工具名称
        contents = parseMarkdownText(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  数字. **工具名称**
        contents = parseBankingToolsOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        //  **工具名称**：
        contents = parseTextOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        // 数字开头的列表格式
        contents = parseBrandsFromTextOptimized(text);
        if (isValidResult(contents)) {
            return contents;
        }
        // 兜底方案 - 使用原始方法
        return parseText(text);
    }


    /**
     * 解析文本中的Reference信息
     * 从文本中提取title和url信息，创建Reference对象列表
     * 支持多种格式：
     * 1. **Title:** 和 **URL:** 格式
     * 2. **title:** 和 **url:** 格式（原有格式）
     *
     * @param text 待解析的文本
     * @return Reference对象列表
     */
    public static List<Reference> parseReferences(String text) {
        List<Reference> references = new ArrayList<>();
        if (text == null || text.isEmpty()) {
            return references;
        }

        // 单次分割，线性扫描
        String[] lines = text.split("\\r?\\n");
        for (int i = 0; i < lines.length; i++) {
            String line = lines[i].trim();
            if (line.isEmpty()) {
                continue;
            }

            // 尝试匹配标题行（支持两种格式）
            String title = extractTitleFromLine(line);
            if (title == null || title.isEmpty()) {
                continue;
            }

            // 在后续最多8行内寻找URL（支持两种格式）
            String url = findUrlInNextLines(lines, i, 8);
            if (url == null || url.isEmpty()) {
                continue;
            }

            // 创建Reference对象
            Reference reference = new Reference();
            reference.setName(title);
            reference.setUrl(url);
            references.add(reference);
        }

        return references;
    }

    /**
     * 从行中提取标题
     * 支持 **Title:**、**title:**、**title示例:** 等多种格式
     *
     * @param line 待解析的行
     * @return 提取的标题，如果未找到返回null
     */
    private static String extractTitleFromLine(String line) {
        // 先将行转换为小写进行匹配
        String lowerLine = line.toLowerCase();

        // 尝试匹配项目符号格式（*   **标题**: ...）
        Matcher titleMatcherBullet = TITLE_LINE_BULLET.matcher(line);
        if (titleMatcherBullet.matches()) {
            String rawTitle = titleMatcherBullet.group(1).trim();
            return unquoteIfNeeded(rawTitle);
        }

        // 尝试匹配新格式（**title:** 或 **title示例:**）
        Matcher titleMatcherNew = TITLE_LINE_NEW.matcher(lowerLine);
        if (titleMatcherNew.matches()) {
            String rawTitle = titleMatcherNew.group(1).trim();
            return unquoteIfNeeded(rawTitle);
        }

        // 尝试匹配原有格式（**title:** 或 **title示例:**）
        Matcher titleMatcher = TITLE_LINE.matcher(line);
        if (titleMatcher.matches()) {
            String rawTitle = titleMatcher.group(2).trim();
            return unquoteIfNeeded(rawTitle);
        }

        return null;
    }

    /**
     * 在后续行中查找URL
     * 支持 **URL:**、**url:**、**url示例:** 等多种格式
     *
     * @param lines      所有行
     * @param startIndex 开始查找的索引
     * @param maxLines   最大查找行数
     * @return 找到的URL，如果未找到返回null
     */
    private static String findUrlInNextLines(String[] lines, int startIndex, int maxLines) {
        for (int j = startIndex + 1; j < Math.min(startIndex + maxLines + 1, lines.length); j++) {
            String urlLine = lines[j].trim();
            if (urlLine.isEmpty()) {
                continue;
            }

            // 尝试匹配项目符号格式（*   **URL**: ...）
            Matcher urlMatcherBullet = URL_LINE_BULLET.matcher(urlLine);
            if (urlMatcherBullet.matches()) {
                String rawUrl = urlMatcherBullet.group(1).trim();
                return unquoteIfNeeded(rawUrl);
            }

            // 先将行转换为小写进行匹配
            String lowerUrlLine = urlLine.toLowerCase();

            // 尝试匹配新格式（**url:** 或 **url示例:**）
            Matcher urlMatcherNew = URL_LINE_NEW.matcher(lowerUrlLine);
            if (urlMatcherNew.matches()) {
                String rawUrl = urlMatcherNew.group(1).trim();
                return unquoteIfNeeded(rawUrl);
            }

            // 尝试匹配原有格式（**url:** 或 **url示例:**）
            Matcher urlMatcher = URL_LINE.matcher(urlLine);
            if (urlMatcher.matches()) {
                String rawUrl = urlMatcher.group(2).trim();
                return unquoteIfNeeded(rawUrl);
            }
        }
        return null;
    }

    /**
     * 去除可能的中英文引号包裹
     */
    private static String unquoteIfNeeded(String value) {
        if (value == null || value.length() < 2) {
            return value;
        }
        char first = value.charAt(0);
        char last = value.charAt(value.length() - 1);
        if ((first == '"' && last == '"') ||
                (first == '\'' && last == '\'') ||
                (first == '"' && last == '"')) {
            return value.substring(1, value.length() - 1).trim();
        }
        return value;
    }

    /**
     * 优化版本的parseText方法
     * 使用预编译的正则表达式，提高性能
     * 过滤掉二级子类（如带缩进的子项目）
     */
    private static List<String> parseTextOptimized(String text) {
        List<String> tools = new ArrayList<>(8); // 预分配容量

        // 按行分割文本，用于检查缩进级别
        String[] lines = text.split("\\r?\\n");

        for (String line : lines) {
            String trimmedLine = line.trim();

            // 跳过空行
            if (trimmedLine.isEmpty()) {
                continue;
            }

            // 检查是否为二级子类（带缩进的项目符号）
            if (isSecondaryItem(line)) {
                continue;
            }

            // 使用预编译的正则表达式匹配 **工具名称**： 格式
            Matcher matcher = PATTERN_TOOL_NAME.matcher(trimmedLine);
            if (matcher.find()) {
                String toolName = matcher.group(1).trim();
                if (!toolName.isEmpty()) {
                    tools.add(toolName);
                    // 如果结果数量已经足够，提前退出
                    if (tools.size() >= MAX_RESULTS) {
                        break;
                    }
                }
            }
        }

        return tools;
    }

    /**
     * 判断是否为二级子类项目
     * 检查行是否以缩进 + 项目符号开头（如 "    - **" 或 "  - **"）
     *
     * @param line 待检查的行
     * @return 是否为二级子类
     */
    private static boolean isSecondaryItem(String line) {
        if (line == null || line.isEmpty()) {
            return false;
        }

        // 检查是否以多个空格或制表符开头，然后是项目符号
        int start = 0;
        int length = line.length();

        // 跳过开头的空白字符 - 使用预定义常量
        while (start < length && (line.charAt(start) == CHAR_SPACE || line.charAt(start) == CHAR_TAB)) {
            start++;
        }

        // 如果缩进少于2个字符，认为是顶级项目
        if (start < 2) {
            return false;
        }

        // 检查是否以项目符号开头 - 使用预定义常量
        if (start < length) {
            char firstChar = line.charAt(start);
            return firstChar == CHAR_DASH || firstChar == CHAR_BULLET ||
                    firstChar == CHAR_MIDDLE_DOT || firstChar == CHAR_ASTERISK;
        }

        return false;
    }

    /**
     * 优化版本的parseMarkdownTools方法
     * 处理 ### 数字. 工具名称 —— 描述 格式的Markdown工具列表
     *
     * @param text 待解析的文本
     * @return 工具名称列表
     */
    private static List<String> parseMarkdownToolsOptimized(String text) {
        List<String> tools = new ArrayList<>(8); // 预分配容量

        // 使用预编译的正则表达式匹配 ### 数字. 工具名称 —— 格式
        Matcher matcher = PATTERN_MARKDOWN_TOOLS.matcher(text);

        while (matcher.find()) {
            String toolName = matcher.group(1).trim();
            if (!toolName.isEmpty()) {
                // 进一步清理工具名称，移除可能的额外空格和特殊字符
                toolName = cleanMarkdownToolName(toolName);
                if (!toolName.isEmpty()) {
                    tools.add(toolName);
                    // 如果结果数量已经足够，提前退出
                    if (tools.size() >= MAX_RESULTS) {
                        break;
                    }
                }
            }
        }

        return tools;
    }

    /**
     * 清理Markdown工具名称 - 优化版本
     * 移除多余的空格、制表符等
     *
     * @param toolName 原始工具名称
     * @return 清理后的工具名称
     */
    private static String cleanMarkdownToolName(String toolName) {
        if (toolName == null || toolName.isEmpty()) {
            return EMPTY_STRING;
        }

        // 移除首尾空白字符
        toolName = toolName.trim();

        // 移除可能的星号标记 - 使用预定义常量
        toolName = toolName.replaceAll("\\*+", EMPTY_STRING);

        // 移除多余的空格，保留单个空格 - 使用预定义常量
        toolName = toolName.replaceAll("\\s+", SPACE);

        return toolName.trim();
    }

    /**
     * 优化版本的parseBankingTools方法
     * 使用预编译的正则表达式，提高性能
     */
    private static List<String> parseBankingToolsOptimized(String text) {
        List<String> tools = new ArrayList<>(8); // 预分配容量

        // 使用预编译的正则表达式
        Matcher matcher = PATTERN_BANKING_TOOLS.matcher(text);

        while (matcher.find()) {
            String toolName = matcher.group(1).trim();
            if (!toolName.isEmpty()) {
                tools.add(toolName);
                // 如果结果数量已经足够，提前退出
                if (tools.size() >= MAX_RESULTS) {
                    break;
                }
            }
        }

        return tools;
    }

    /**
     * 解析以粗体包裹的编号标题，例如：**1. MarketUP**
     */
    private static List<String> parseBoldNumberedList(String text) {
        List<String> tools = new ArrayList<>(8);
        Matcher matcher = PATTERN_BOLD_NUMBERED.matcher(text);
        while (matcher.find()) {
            String toolName = matcher.group(1).trim();
            if (!toolName.isEmpty()) {
                tools.add(toolName);
                if (tools.size() >= MAX_RESULTS) {
                    break;
                }
            }
        }
        return tools;
    }

    /**
     * 优化版本的parseBrandsFromText方法
     * 减少字符串操作，提高性能
     */
    private static List<String> parseBrandsFromTextOptimized(String text) {
        if (text == null || text.isEmpty()) {
            return new ArrayList<>();
        }

        List<String> brands = new ArrayList<>(16);
        int start = 0;
        int length = text.length();

        while (start < length) {
            int end = text.indexOf(CHAR_NEWLINE, start);
            if (end == -1) {
                end = length;
            }

            // 快速检查行长度，跳过过短的行
            if (end - start < 3) {
                start = end + 1;
                continue;
            }

            String line = text.substring(start, end).trim();
            start = end + 1;

            // 跳过空行
            if (line.isEmpty()) {
                continue;
            }

            // 快速检查是否以数字开头（比containsDigit更高效）
            if (!Character.isDigit(line.charAt(0))) {
                continue;
            }

            // 优化字符串清理
            String cleanedLine = cleanLineOptimized(line);
            if (!cleanedLine.isEmpty()) {
                String brand = extractBrandOptimized(cleanedLine);
                if (!brand.isEmpty()) {
                    brands.add(brand);
                    // 如果结果数量已经足够，提前退出
                    if (brands.size() >= MAX_RESULTS) {
                        break;
                    }
                }
            }
        }

        return brands;
    }

    /**
     * 优化版本的cleanLine方法
     * 减少字符串创建，提高性能
     */
    private static String cleanLineOptimized(String line) {
        int start = 0;
        int length = line.length();

        // 移除开头的数字序号
        while (start < length && Character.isDigit(line.charAt(start))) {
            start++;
        }
        if (start < length && (line.charAt(start) == CHAR_DOT || line.charAt(start) == CHAR_CHINESE_DOT)) {
            start++;
        }
        while (start < length && Character.isWhitespace(line.charAt(start))) {
            start++;
        }

        // 移除开头的项目符号 - 使用预定义常量
        if (start < length) {
            char firstChar = line.charAt(start);
            if (firstChar == CHAR_BULLET || firstChar == CHAR_MIDDLE_DOT || firstChar == CHAR_DASH) {
                start++;
                while (start < length && Character.isWhitespace(line.charAt(start))) {
                    start++;
                }
            }
        }

        // 移除开头的冒号 - 使用预定义常量
        if (start < length && (line.charAt(start) == CHAR_CHINESE_COLON || line.charAt(start) == CHAR_COLON)) {
            start++;
            while (start < length && Character.isWhitespace(line.charAt(start))) {
                start++;
            }
        }

        // 如果start已经等于length，直接返回空字符串
        if (start >= length) {
            return EMPTY_STRING;
        }

        // 移除星号，使用更高效的方式 - 使用预定义常量
        StringBuilder sb = new StringBuilder(length - start);
        for (int i = start; i < length; i++) {
            char c = line.charAt(i);
            if (c != CHAR_ASTERISK) {
                sb.append(c);
            }
        }

        return sb.toString();
    }

    /**
     * 优化版本的extractBrand方法
     * 使用更高效的分隔符查找
     */
    private static String extractBrandOptimized(String line) {
        int length = line.length();

        // 按优先级查找分隔符，使用单次遍历 - 使用预定义常量
        for (int i = 0; i < length; i++) {
            char c = line.charAt(i);
            if (c == CHAR_CHINESE_COLON || c == CHAR_COLON ||
                    c == CHAR_CHINESE_SEMICOLON || c == CHAR_SEMICOLON) {
                return line.substring(0, i).trim();
            }
        }

        return line.trim();
    }


    /**
     * 判断第一个是否数字的方式
     */
    private static List<String> parseBrandsFromText(String text) {
        if (text == null || text.isEmpty()) {
            return new ArrayList<>();
        }

        // 预分配容量，减少扩容开销
        List<String> brands = new ArrayList<>(16);

        // 使用更高效的字符遍历方式
        int start = 0;
        int length = text.length();

        while (start < length) {
            int end = text.indexOf(CHAR_NEWLINE, start);
            if (end == -1) {
                end = length;
            }

            // 直接提取行内容，避免split创建数组
            String line = text.substring(start, end).trim();
            start = end + 1;

            // 跳过空行
            if (line.isEmpty()) {
                continue;
            }

            // 快速检查是否包含数字（比正则表达式更高效）
            if (!containsDigit(line)) {
                continue;
            }

            // 优化字符串清理：使用StringBuilder减少字符串创建
            String cleanedLine = cleanLine(line);
            if (!cleanedLine.isEmpty()) {
                String brand = extractBrand(cleanedLine);
                if (!brand.isEmpty()) {
                    brands.add(brand);
                }
            }
        }

        return brands;
    }

    /**
     * 从文本中提取 **工具名称**： 格式的工具名称
     */
    private static List<String> parseText(String text) {
        List<String> tools = new ArrayList<>();

        // 按行分割文本
        String[] lines = text.split("\\r?\\n");

        for (String line : lines) {
            line = line.trim();

            // 查找包含 **工具名称**： 格式的行 - 使用预定义常量
            if (line.contains(ASTERISK + ASTERISK) && line.contains(CHINESE_COLON)) {
                String toolName = extractToolName(line);
                if (toolName != null && !toolName.isEmpty()) {
                    tools.add(toolName);
                }
            }
        }

        return tools;
    }


    /**
     * 按行分割文本
     */
    private static List<String> splitTextByLine(String text) {
        List<String> tools = new ArrayList<>();
        // 按行分割文本
        String[] lines = text.split("\\r?\\n");

        for (String line : lines) {
            tools.add(line.trim());
        }
        return tools;
    }


    /**
     * 解析银行拓客工具名称
     * 从文本中提取数字. **工具名称** 格式的工具名称
     *
     * @param text 待解析的文本
     * @return 工具名称列表
     */
    private static List<String> parseBankingTools(String text) {
        List<String> tools = new ArrayList<>();

        // 使用正则表达式匹配 "数字. **工具名称**" 格式
        Pattern pattern = Pattern.compile("\\d+\\.\\s*\\*\\*([^*]+)\\*\\*");
        Matcher matcher = pattern.matcher(text);

        while (matcher.find()) {
            String toolName = matcher.group(1).trim();
            if (!toolName.isEmpty()) {
                tools.add(toolName);
            }
        }

        return tools;
    }


    /**
     * 从工具行中提取工具名称
     *
     * @param line 包含工具信息的行
     * @return 工具名称，如果提取失败返回null
     */
    private static String extractToolName(String line) {
        // 使用正则表达式匹配 **工具名称**： 格式
        Pattern pattern = Pattern.compile("\\*\\*([^*]+)\\*\\*：");
        Matcher matcher = pattern.matcher(line);

        if (matcher.find()) {
            return matcher.group(1).trim();
        }

        return null;
    }


    /**
     * 快速检查字符串是否包含数字
     */
    private static boolean containsDigit(String str) {
        for (int i = 0; i < str.length(); i++) {
            if (Character.isDigit(str.charAt(i))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 清理行内容，移除序号和标点符号
     */
    private static String cleanLine(String line) {
        int start = 0;
        int length = line.length();

        // 移除开头的数字序号
        while (start < length && Character.isDigit(line.charAt(start))) {
            start++;
        }
        if (start < length && (line.charAt(start) == CHAR_DOT || line.charAt(start) == CHAR_CHINESE_DOT)) {
            start++;
        }
        while (start < length && Character.isWhitespace(line.charAt(start))) {
            start++;
        }

        // 移除开头的项目符号 - 使用预定义常量
        if (start < length) {
            char firstChar = line.charAt(start);
            if (firstChar == CHAR_BULLET || firstChar == CHAR_MIDDLE_DOT || firstChar == CHAR_DASH) {
                start++;
                while (start < length && Character.isWhitespace(line.charAt(start))) {
                    start++;
                }
            }
        }

        // 移除开头的冒号 - 使用预定义常量
        if (start < length && (line.charAt(start) == CHAR_CHINESE_COLON || line.charAt(start) == CHAR_COLON)) {
            start++;
            while (start < length && Character.isWhitespace(line.charAt(start))) {
                start++;
            }
        }

        // 移除星号 - 使用预定义常量
        StringBuilder sb = new StringBuilder(length - start);
        for (int i = start; i < length; i++) {
            if (line.charAt(i) != CHAR_ASTERISK) {
                sb.append(line.charAt(i));
            }
        }

        return sb.toString();
    }

    /**
     * 提取品牌名称 - 优化版本
     */
    private static String extractBrand(String line) {
        // 按优先级查找分隔符 - 使用预定义常量
        int index = -1;
        char separator = 0;

        // 中文冒号优先级最高
        if ((index = line.indexOf(CHAR_CHINESE_COLON)) != -1) {
            separator = CHAR_CHINESE_COLON;
        } else if ((index = line.indexOf(CHAR_COLON)) != -1) {
            separator = CHAR_COLON;
        } else if ((index = line.indexOf(CHAR_CHINESE_SEMICOLON)) != -1) {
            separator = CHAR_CHINESE_SEMICOLON;
        } else if ((index = line.indexOf(CHAR_SEMICOLON)) != -1) {
            separator = CHAR_SEMICOLON;
        }

        if (index != -1) {
            return line.substring(0, index).trim();
        }

        return line.trim();
    }


    /**
     * 专门解析DeepSeek文本中的工具名称
     * 处理 ### 数字. 工具名称 格式，如：
     * - ### 1. HubSpot
     * - ### 2. Marketo Engage (Adobe旗下)
     *
     * @param text 待解析的文本
     * @return 工具名称列表
     */
    private static List<String> parseMarkdownText(String text) {
        if (text == null || text.isEmpty()) {
            return new ArrayList<>();
        }

        List<String> tools = new ArrayList<>();
        String[] lines = text.split("\\r?\\n");

        for (String line : lines) {
            String trimmedLine = line.trim();
            if (trimmedLine.isEmpty()) {
                continue;
            }

            // 匹配 ### 数字. 工具名称 格式
            if (trimmedLine.matches("^###\\s*\\d+\\.\\s*.+")) {
                // 提取工具名称：移除 ### 数字. 前缀
                String toolName = trimmedLine.replaceFirst("^###\\s*\\d+\\.\\s*", "").trim();
                if (!toolName.isEmpty()) {
                    tools.add(toolName);
                }
            }
        }

        return tools;
    }

    /**
     * 专门解析带星号的Markdown格式文本中的工具名称
     * 处理 ### **数字. 工具名称（公司名）** 格式，如：
     * - ### **1. 数商云（广州市数商云网络科技有限公司）**
     * - ### **2. 星谷云（上海星谷信息科技有限公司）**
     *
     * @param text 待解析的文本
     * @return 工具名称列表
     */
    private static List<String> parseBoldMarkdownText(String text) {
        if (text == null || text.isEmpty()) {
            return new ArrayList<>();
        }

        List<String> tools = new ArrayList<>();
        String[] lines = text.split("\\r?\\n");

        for (String line : lines) {
            String trimmedLine = line.trim();
            if (trimmedLine.isEmpty()) {
                continue;
            }

            // 匹配 ### **数字. 工具名称（公司名）** 格式
            if (trimmedLine.matches("^###\\s*\\*\\*\\d+\\.\\s*.+\\*\\*$")) {
                // 提取工具名称：移除 ### **数字. 前缀和末尾的**
                String toolName = trimmedLine
                        .replaceFirst("^###\\s*\\*\\*\\d+\\.\\s*", "")  // 移除 ### **数字. 前缀
                        .replaceFirst("\\*\\*$", "")  // 移除末尾的**
                        .trim();
                if (!toolName.isEmpty()) {
                    tools.add(toolName);
                }
            }
        }

        return tools;
    }

    /**
     * 专门解析新格式的Reference信息
     * 处理 **Title:** 和 **URL:** 格式
     *
     * @param text 待解析的文本
     * @return Reference对象列表
     */
    private static List<Reference> parseReferencesNewFormat(String text) {
        if (text == null || text.isEmpty()) {
            return new ArrayList<>();
        }

        List<Reference> references = new ArrayList<>();
        String[] lines = text.split("\\r?\\n");

        for (int i = 0; i < lines.length; i++) {
            String line = lines[i].trim();
            if (line.isEmpty()) {
                continue;
            }

            // 只匹配新格式 **Title:** 和 **URL:**
            Matcher titleMatcher = TITLE_LINE_NEW.matcher(line);
            if (!titleMatcher.matches()) {
                continue;
            }

            String title = unquoteIfNeeded(titleMatcher.group(1).trim());
            if (title == null || title.isEmpty()) {
                continue;
            }

            // 在后续最多8行内寻找URL
            String url = null;
            for (int j = i + 1; j < Math.min(i + 9, lines.length); j++) {
                String urlLine = lines[j].trim();
                if (urlLine.isEmpty()) {
                    continue;
                }
                Matcher urlMatcher = URL_LINE_NEW.matcher(urlLine);
                if (urlMatcher.matches()) {
                    url = unquoteIfNeeded(urlMatcher.group(1).trim());
                    break;
                }
            }

            if (url != null && !url.isEmpty()) {
                Reference reference = new Reference();
                reference.setName(title);
                reference.setUrl(url);
                references.add(reference);
            }
        }

        return references;
    }

    /**
     * 验证解析结果是否有效
     *
     * @param contents 解析结果
     * @return 是否有效
     */
    private static boolean isValidResult(List<String> contents) {
        return contents != null && !contents.isEmpty() && contents.size() <= VALID_MAX_RESULTS;
    }
}
